_Pragma("once");

#include <fcntl.h>
#include <string>
#include <unistd.h>

#include "SingletonTemplate.h"

class BasicDevice {
public:
    /** Default constructor */
    BasicDevice(const std::string& deviceName, const int oflags = O_RDWR | O_CLOEXEC, const int modes = 0);

    BasicDevice(const int oflags = O_RDWR | O_CLOEXEC, const int modes = 0) : moflags(oflags), mmodes(modes){
    }

    /** Default destructor */
    virtual ~BasicDevice();

    int reopen(){
        deviceFd = openFd(deviceName.data(), moflags, mmodes);

        return deviceFd;
    }

    bool close(){
        bool result = false;
        if (this->operator bool()){
            result = closeFd(deviceFd);
            deviceFd = -1;
        }

        return result;
    }

    bool syncToPersistence(){
        return 0 == ::fsync(deviceFd);
    }


    int getDeviceFd(){
        return deviceFd;
    }

    operator bool(){
        return 0 < deviceFd;
    }


    static int openFd(const std::string& deviceName, const int oflags, const int modes);
    static bool closeFd(const int fd);


    std::string deviceName;

    const int moflags = O_RDWR | O_CLOEXEC;
    const int mmodes = 0;
protected:
    int deviceFd = -1; //!< Member variable "deviceFd"

};

